package com.zxd.interview.desginpattern.single;

import com.zxd.interview.util.ExecuteUtil;

/**
 * 单例模式 - 懒汉式
 *
 * @author zhaoxudong
 * @version 1.0
 * @date 2020/10/27 21:45
 */
public class SingleLazy {

    public static void main(String[] args) {
        // 常规多线程
//        for (int i = 0; i < 100; i++) {
//            new TestRunThread().start();
//        }
        try {
            ExecuteUtil.startTaskAllInOnce(50000, new TestRunThread());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 模拟异步请求
 * 模拟十组数据
 */
class TestRunThread extends Thread {

    @Override
    public void run() {
        // 懒汉式第一版
//        int i = LazyVersion1.getInstance().hashCode();
        // 懒汉式第二版
//        int i = LazyVersion2.getInstance1().hashCode();
        // 懒汉式第三版
        int i = SingleLazyVersion2.getInstance2().hashCode();
        System.err.println(i);
    }
}

/**
 * 饿汉式的第一版本
 */
class SingleLazyVersion1 {

    private static SingleLazyVersion1 lazyVersion1;

    public static SingleLazyVersion1 getInstance() {
        if (lazyVersion1 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lazyVersion1 = new SingleLazyVersion1();
        }
        return lazyVersion1;
    }


}

/**
 * 懒汉式的第二版本
 * 1. 直接对整个方法加锁
 * 2. 在局部代码块加锁
 */
class SingleLazyVersion2 {

    /**
     * 使用volatile 避免指令重排序
     */
    private static volatile SingleLazyVersion2 lazyVersion2;

    /**
     * 在方法的整体加入 synchronized
     *
     * @return
     */
    public synchronized static SingleLazyVersion2 getInstance1() {
        if (lazyVersion2 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lazyVersion2 = new SingleLazyVersion2();
        }
        return lazyVersion2;
    }

    /**
     * 在局部代码快加入 synchronized
     *
     * @return
     */
    public static SingleLazyVersion2 getInstance2() {
        if (lazyVersion2 == null) {
            // 验证是否创建多个对象
            try {
                // 模拟在创建对象之前做一些准备工作
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (SingleLazyVersion2.class) {
                if (lazyVersion2 == null) {
                    lazyVersion2 = new SingleLazyVersion2();
                }
            }
        }
        return lazyVersion2;
    }


}

